package com.ruoyi.order.config;

import com.alipay.api.AlipayApiException;
import com.alipay.api.AlipayClient;
import com.alipay.api.DefaultAlipayClient;
import com.alipay.api.internal.util.AlipaySignature;
import com.alipay.api.request.AlipayTradePagePayRequest;
import com.ruoyi.order.domain.TbOrder;
import com.ruoyi.order.service.ITbOrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @author : gaohuaida
 * @author : Mild-mannered soul programmer🎶
 * @date : 2024-08-28 08:35
 * @description :
 * 支付宝沙箱支付控制器
 **/
@RestController
@RequestMapping("/alipay")
public class AlipayController {


    @Autowired
    private ITbOrderService orderService; // 注入订单服务

    // 支付宝配置类（需确保 AliPayConfig 可正确引用）
    private static final String GATEWAY_URL = AliPayConfig.gatewayUrl;
    private static final String APP_ID = AliPayConfig.app_id;
    private static final String MERCHANT_PRIVATE_KEY = AliPayConfig.merchant_private_key;
    private static final String ALIPAY_PUBLIC_KEY = AliPayConfig.alipay_public_key;
    private static final String CHARSET = AliPayConfig.charset;
    private static final String SIGN_TYPE = AliPayConfig.sign_type;


    @GetMapping("/pay")
    public String alipay(String orderNo, HttpServletResponse response) throws Exception {
        // 1. 验证订单号参数
        if (!StringUtils.hasText(orderNo)) {
            return "订单号不能为空";
        }

        // 2. 根据订单号查询真实订单
        TbOrder order = orderService.getByOrderNo(orderNo);
        if (order == null) {
            return "订单不存在"; // 或抛自定义异常
        }

        // 3. 验证订单关键字段
        if (!StringUtils.hasText(order.getOrderNo())) {
            // 添加日志记录，便于排查
            System.out.println("警告：订单对象存在但订单号字段为空，订单ID：" + order.getOrderId());
            return "订单编号为空，无法支付";
        }

        // 4. 组装支付宝请求参数（用订单真实数据）
        String out_trade_no = order.getOrderNo();          // 订单编号
        String total_amount = order.getOrderAmount() != null ? order.getOrderAmount().toString() : "0.00"; // 订单金额
        String subject = "拼夕夕订单-" + out_trade_no;     // 订单标题（可更详细）
        String body = "服务时长：" + (order.getServiceDuration() != null ? order.getServiceDuration() : "0") + "分钟，里程：" + (order.getServiceMileage() != null ? order.getServiceMileage() : "0") + "公里";

        // 5. 初始化支付宝客户端
        AlipayClient alipayClient = new DefaultAlipayClient(
                GATEWAY_URL, APP_ID, MERCHANT_PRIVATE_KEY,
                "json", CHARSET, ALIPAY_PUBLIC_KEY, SIGN_TYPE
        );

        // 6. 设置支付请求
        AlipayTradePagePayRequest alipayRequest = new AlipayTradePagePayRequest();
        alipayRequest.setReturnUrl("http://localhost:80"); // 同步回调（需外网可访问时替换）
        alipayRequest.setNotifyUrl(AliPayConfig.notify_url); // 异步回调

        // 构造业务参数
        alipayRequest.setBizContent("{\"out_trade_no\":\"" + out_trade_no + "\"," +
                "\"total_amount\":\"" + total_amount + "\"," +
                "\"subject\":\"" + subject + "\"," +
                "\"body\":\"" + body + "\"," +
                "\"product_code\":\"FAST_INSTANT_TRADE_PAY\"}");

        // 7. 发起支付请求
        String result = alipayClient.pageExecute(alipayRequest).getBody();
        System.out.println("支付宝返回表单：" + result);
        return result;
    }


    @PostMapping("/alipayNotify") // 注意改为 POST！支付宝异步通知是 POST 请求
    public String alipayNotify(HttpServletRequest request) throws AlipayApiException {
        System.out.println("收到支付宝异步回调...");

        // 1. 解析请求参数
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        // 2. 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(
                params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE
        );

        if (signVerified) {
            // 3. 解析关键参数
            String out_trade_no = request.getParameter("out_trade_no"); // 订单号
            String trade_no = request.getParameter("trade_no");         // 支付宝交易号
            String trade_status = request.getParameter("trade_status"); // 交易状态

            // 4. 根据订单号查询订单
            TbOrder order = orderService.getByOrderNo(out_trade_no);
            if (order == null) {
                return "订单不存在";
            }

            // 5. 匹配状态字典（示例：字典值 2 对应“已支付”）
            // 可通过若依字典工具类 DictUtils.getDictLabel 转换，需注入 DictService
            // 这里先硬编码演示，实际用工具类更优雅：
            // String statusLabel = DictUtils.getDictLabel(String.valueOf(order.getOrderStatus()), "order_status", "");

            // 6. 更新订单状态与支付时间
            if ("TRADE_SUCCESS".equals(trade_status) || "TRADE_FINISHED".equals(trade_status)) {
                order.setOrderStatus(2L); // 假设字典“已支付”对应值为 2
                order.setPaymentTime(new java.util.Date());
                orderService.updateById(order);
            }

            return "SUCCESS"; // 必须返回 SUCCESS，否则支付宝会重复通知
        } else {
            System.out.println("签名验证失败！");
            return "fail";
        }
    }


    @GetMapping("/alipayReturn")
    public String alipayReturn(HttpServletRequest request) throws AlipayApiException {
        System.out.println("收到支付宝同步回调...");

        // 1. 解析参数（同异步通知逻辑）
        Map<String, String> params = new HashMap<>();
        Map<String, String[]> requestParams = request.getParameterMap();
        for (Iterator<String> iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = iter.next();
            String[] values = requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            params.put(name, valueStr);
        }

        // 2. 验证签名
        boolean signVerified = AlipaySignature.rsaCheckV1(
                params, ALIPAY_PUBLIC_KEY, CHARSET, SIGN_TYPE
        );

        if (signVerified) {
            // 3. 跳转前端（带订单号，方便前端查询状态）
            String out_trade_no = request.getParameter("out_trade_no");
            return "redirect:http://localhost:8080/#/order/detail?orderNo=" + out_trade_no;
        } else {
            return "验签失败！";
        }
    }

}